SoC 系统集成 AXI FPGA完整设计
最后一课,我们将前24课的所有知识整合为一个完整的通用CA片上系统(SoC)——支持1D/2D CA、多种规则、可编程邻域、VGA显示、UART控制、流水线加速。
┌─────────────────────────────────────────────────┐ │ Universal CA SoC │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ AXI Interconnect │ │ │ └──┬──────┬───────┬──────┬────────┬────────┘ │ │ │ │ │ │ │ │ │ ┌──▼──┐┌──▼──┐┌───▼──┐┌──▼──┐┌───▼────┐ │ │ │UART ││VGA ││CA ││Rule ││Memory │ │ │ │Ctrl ││Ctrl ││Core ││RAM ││Ctrl │ │ │ │ ││ ││×4 ││ ││DDR3 │ │ │ └─────┘└─────┘└──────┘└─────┘└────────┘ │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ CPU (MicroBlaze/RISC-V) │ │ │ └──────────────────────────────────────────┘ │ └─────────────────────────────────────────────────┘
// ============================================================================
// ca_soc_top.v - 通用CA SoC顶层模块
// 集成:CA核心阵列 + 规则存储 + VGA显示 + UART控制 + DDR接口
// ============================================================================
module ca_soc_top #(
parameter GRID_W = 256,
parameter GRID_H = 256
)(
// ---- 时钟和复位 ----
input wire clk_100mhz,
input wire rst_n,
// ---- UART接口 ----
input wire uart_rx,
output wire uart_tx,
// ---- VGA接口 ----
output wire [3:0] vga_r,
output wire [3:0] vga_g,
output wire [3:0] vga_b,
output wire vga_hsync,
output wire vga_vsync,
// ---- LED/按钮 ----
output wire [7:0] led,
input wire [3:0] btn,
// ---- DDR3接口 ----
output wire ddr3_clk,
output wire ddr3_rst_n,
output wire [14:0] ddr3_addr,
output wire [2:0] ddr3_ba,
output wire ddr3_cas_n,
output wire ddr3_ras_n,
output wire ddr3_we_n,
inout wire [15:0] ddr3_dq,
inout wire [1:0] ddr3_dqs_n,
inout wire [1:0] ddr3_dqs_p
);
// ---- 内部信号 ----
wire [31:0] cpu_addr, cpu_wdata, cpu_rdata;
wire cpu_valid, cpu_ready;
wire [3:0] cpu_wstrb;
// ---- CA核心信号 ----
wire [7:0] ca_rule;
wire ca_enable, ca_init, ca_mode; // 0=1D, 1=2D
wire [31:0] ca_step;
wire [31:0] ca_population;
// ---- VGA信号 ----
wire [9:0] vga_x, vga_y;
wire vga_active;
wire [23:0] vga_rgb;
// ---- PLL时钟生成 ----
wire clk_25mhz, clk_200mhz, clk_locked;
pll_core u_pll (
.clk_in (clk_100mhz),
.clk_25 (clk_25mhz), // VGA像素时钟
.clk_200 (clk_200mhz), // DDR3时钟
.locked (clk_locked)
);
// ---- 简单CPU (状态机式) ----
ca_cpu u_cpu (
.clk (clk_100mhz),
.rst_n (rst_n && clk_locked),
.uart_rx (uart_rx),
.uart_tx (uart_tx),
.addr (cpu_addr),
.wdata (cpu_wdata),
.rdata (cpu_rdata),
.valid (cpu_valid),
.ready (cpu_ready),
.wstrb (cpu_wstrb)
);
// ---- CA核心阵列 ----
ca_core_array #(.WIDTH(GRID_W), .HEIGHT(GRID_H)) u_ca (
.clk (clk_100mhz),
.rst_n (rst_n && clk_locked),
.enable (ca_enable),
.init (ca_init),
.rule (ca_rule),
.mode_2d (ca_mode),
.step_count (ca_step),
.population (ca_population),
.state_out () // 连接到VGA和DDR
);
// ---- VGA显示控制器 ----
vga_controller u_vga (
.clk25 (clk_25mhz),
.rst_n (rst_n && clk_locked),
.hcount (vga_x),
.vcount (vga_y),
.hsync (vga_hsync),
.vsync (vga_vsync),
.blank (),
.active (vga_active)
);
// ---- LED显示状态 ----
assign led[0] = ca_enable;
assign led[1] = ca_init;
assign led[2] = ca_mode;
assign led[7:3] = ca_rule[7:3];
endmodule
| 模块 | LUTs | FFs | BRAM | DSP |
|---|---|---|---|---|
| CA核心阵列(4核) | ~50K | ~30K | 4 | 0 |
| 规则存储 | ~1K | ~500 | 1 | 0 |
| VGA控制器 | ~2K | ~1K | 2 | 0 |
| UART控制器 | ~500 | ~300 | 0 | 0 |
| DDR3控制器 | ~10K | ~5K | 2 | 0 |
| CPU | ~5K | ~3K | 4 | 0 |
| AXI互连 | ~3K | ~2K | 0 | 0 |
| 总计 | ~72K | ~42K | 13 | 0 |
| 命令 | 格式 | 说明 |
|---|---|---|
| SET_RULE | 0x01 + rule_byte | 设置CA规则 |
| INIT | 0x02 + seed_h + seed_l | 初始化种子 |
| STEP | 0x03 | 执行一步 |
| RUN | 0x04 + speed_byte | 连续运行 |
| HALT | 0x05 | 停止 |
| GET_STATE | 0x06 + addr_h + addr_l | 读取状态 |
| SET_MODE | 0x07 + mode_byte | 0=1D, 1=2D |
恭喜你完成了全部25课!你已经从最基本的一维CA概念,走到了完整的SoC系统设计。
你现在具备了:
"自然界最复杂的系统,可能只是简单规则在巨大规模上的运行。" — Stephen Wolfram
元胞自动机教会我们的最重要一课:复杂性不需要复杂的起源。从三条规则的生命游戏到256种Wolfram规则,从HPP碰撞到Navier-Stokes方程,从两条蚂蚁规则到高速公路——简单规则,无限可能。
带着这个洞察,去创造吧!🚀
系统级验证策略:
1. 单元测试:每个模块独立验证
- CA核心:已知输入→已知输出
- VGA控制器:时序合规性检查
- UART:回环测试
2. 集成测试:模块间接口验证
- CA→VGA数据通路
- CPU→CA配置通路
3. 系统测试:端到端功能验证
- 发送命令→观察VGA输出
- 长时间运行稳定性测试
覆盖率指标:
功能覆盖率:所有命令是否都被测试?
代码覆盖率:所有Verilog分支是否都被执行?
时序覆盖率:所有时钟域交叉是否都被验证?
// 系统监视器 - SoC运行状态监视
module system_monitor #(
parameter GRID_W = 256,
parameter GRID_H = 256
)(
input wire clk,
input wire rst_n,
input wire ca_running,
input wire [31:0] ca_steps,
input wire [31:0] ca_population,
input wire vga_active,
input wire uart_activity,
output wire [31:0] uptime_cycles,
output wire [15:0] steps_per_second,
output wire [7:0] system_status, // bit flags
output wire watchdog_ok
);
reg [31:0] cycle_cnt;
reg [31:0] last_step_cnt;
reg [15:0] sps;
reg [31:0] sps_timer;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cycle_cnt <= 32'd0;
last_step_cnt <= 32'd0;
sps <= 16'd0;
sps_timer <= 32'd0;
end else begin
cycle_cnt <= cycle_cnt + 32'd1;
sps_timer <= sps_timer + 32'd1;
// 每秒计算一次SPS
if (sps_timer >= 32'd100_000_000) begin
sps <= (ca_steps - last_step_cnt)[15:0];
last_step_cnt <= ca_steps;
sps_timer <= 32'd0;
end
end
end
assign uptime_cycles = cycle_cnt;
assign steps_per_second = sps;
assign system_status = {ca_running, vga_active, uart_activity, 5'd0};
assign watchdog_ok = (sps > 16'd0) || !ca_running;
endmodule
SoC部署清单:
✅ 功能仿真通过(所有testbench)
✅ 综合无错误无警告
✅ 时序约束满足(所有路径)
✅ 布局布线后仿真通过
✅ FPGA配置文件生成成功
✅ 下载到开发板验证
✅ 长时间运行稳定性测试(24h+)
✅ 功耗分析通过
恭喜!你已经完成了从理论到完整系统的全过程!🎉
元胞自动机课程 · 从Conway到Langton到Lattice Gas